﻿using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Data.OleDb;
using System.Collections;

/// <summary>
/// The CartData class manages the data in memory for a book store shopping cart. 
/// It contains a DataTable who's rows are items in the cart.
/// The DataRow fields are ISBN, Title, Quantity, and Price.
/// The book Title and Price are loaded from the Books table in the database specified by the connection string in the web.config file.
/// The DataTable can be extracted and viewed by the user.
/// This class also provides static methods for retreiving and saving an instance of itself to a HTTPSession object.
/// </summary>
public class CartData
{
    DataTable cartTable;
    /// <summary>
    /// Key name of the Session entry for the CartData object
    /// </summary>
    public const string CART_SESSION_KEY = "Cart";

    /// <summary>
    /// Default Constructor
    /// </summary>
	public CartData()
    {
        createCartTable();
    }

    /// <summary>
    /// Retrieves a CartData object from the Session object and passes it to the caller
    /// </summary>
    /// <param name="page">
    /// A Page object used for retrieving the CartData object from the Session
    /// </param>
    /// <returns>
    /// A CartData object
    /// </returns>
    public static CartData getCartFromSession(Page page)
    {

        if (page.Session[CART_SESSION_KEY] != null)
        {
            return (CartData)page.Session[CART_SESSION_KEY];
        }
        else 
        { 
            CartData cart = new CartData();
            return cart;
        }

    }//end getCartFromSession

    /// <summary>
    /// Saves a CartData object to the Session object in the page paramenter
    /// </summary>
    /// <param name="page">
    /// Holds a reference to the Page object for the purpose of saving the CartData object to the Page Session
    /// </param>
    /// <param name="cart">
    /// CartData object to save in the Page Session
    /// </param>
    public static void saveCartToSession(Page page, CartData cart)
    {
        page.Session[CART_SESSION_KEY] = cart;

    }//end saveCartToSession

    /// <summary>
    /// Creates the structure for the cartTable DataTable
    /// </summary>
    private void createCartTable()
    {
        //set data types for fields
        Type typeString = Type.GetType("System.String");
        Type typeInt16 = Type.GetType("System.Int16");
        Type typeDecimal = Type.GetType("System.Decimal");

        //create table columns
        DataColumn isbnColumn = new DataColumn("ISBN", typeString);
        DataColumn titleColumn = new DataColumn("Title", typeString);
        DataColumn quantityColumn = new DataColumn("Quantity", typeInt16);
        DataColumn priceColumn = new DataColumn("Price", typeDecimal);

        //create cart table and add columns
        cartTable = new DataTable("Cart");
        cartTable.Columns.Add(isbnColumn);
        cartTable.Columns.Add(titleColumn);
        cartTable.Columns.Add(quantityColumn);
        cartTable.Columns.Add(priceColumn);

    }//end createCartTable

    /// <summary>
    /// Retrieves the record from the Books table specified by the 'isbn' parameter
    /// </summary>
    /// <param name="isbn">
    /// isbn of the record to retrieve
    /// </param>
    /// <returns>
    /// A DataRow containing the record from the Books table that matches the isbn parameter
    /// </returns>
    private DataRow getBookDataRow(string isbn)
    {
        //define data objects
        string connectionString;
        connectionString = 
            ConfigurationManager.ConnectionStrings["BooksDataSet"].ConnectionString;
        OleDbConnection con = new OleDbConnection(connectionString);
        string selectSQL;
        selectSQL = "SELECT ISBN,Title,Price FROM Books WHERE ISBN = @ISBN";
        OleDbCommand cmd = new OleDbCommand(selectSQL, con);
        cmd.Parameters.AddWithValue("@ISBN",isbn);
        OleDbDataAdapter adapter = new OleDbDataAdapter(cmd);
        DataSet books = new DataSet();


        //open database and fill dataset
        try
        {
            con.Open();
            adapter.Fill(books, "Books");

            //return the row with the isbn matching the parameter
            return books.Tables["Books"].Rows[0];
        }
        catch (Exception e)
        {
            throw e;
        }
        finally
        {
            con.Close();
        }

    }//end getBookDataRow

    /// <summary>
    /// Retrieves the DataTable object from an instance of this class
    /// </summary>
    /// <returns>
    /// A DataTable object containing all of the records in the DataTable
    /// </returns>
    public DataTable getCartTable() { return cartTable; }

    /// <summary>
    /// Adds a new item to the shopping cart.
    /// </summary>
    /// <param name="isbn">
    /// isbn of the book to be added to the cart
    /// </param>
    /// <param name="quantity">
    /// quantity of items to be added to the cart
    /// </param>
    public void addItem(string isbn, int quantity)
    {
        //if the book is already in the cart, return
        if (exists(isbn)) { return; }

        //create data objects
        DataRow bookRow = getBookDataRow(isbn);
        DataRow cartRow = cartTable.NewRow();

        //fill the datarow
        cartRow["ISBN"] = isbn;
        cartRow["Title"] = bookRow["Title"];
        cartRow["Quantity"] = quantity;
        cartRow["Price"] = bookRow["Price"];

        //add the row to the dataset
        cartTable.Rows.Add(cartRow);

    }//end addItem

    /// <summary>
    /// Removes an item from the shopping cart.
    /// </summary>
    /// <param name="isbn">
    /// isbn of the item to be removed from the shopping cart
    /// </param>
    public void removeItem(string isbn)
    {
        //if the row doesn't exist, return
        if (!exists(isbn)) { return; }

        //search for the row to delete
        DataRow deleteRow = getRow(isbn);

        //if found, delete it
        if (deleteRow != null)
        {
            cartTable.Rows.Remove(deleteRow);
        }//end if
    }//end removeItem

    /// <summary>
    /// Get a specific row from the shopping cart.
    /// </summary>
    /// <param name="isbn">
    /// isbn of the item to be retrieved
    /// </param>
    /// <returns>
    /// A DataRow containing the specified item. If the item does not exist, returns null.
    /// </returns>
    private DataRow getRow(string isbn)
    {
        foreach (DataRow dRow in cartTable.Rows)
        {
            if (dRow["ISBN"].ToString().CompareTo(isbn) == 0)
            {
                return dRow;
            }//end if
        }//end foreach
        return null;
    }//end getRow

    /// <summary>
    /// Checks if the specified item is in the shopping cart.
    /// </summary>
    /// <param name="isbn">
    /// isbn of the item to check
    /// </param>
    /// <returns>
    /// True if the item is present. False if not.
    /// </returns>
    public bool exists(string isbn)
    {
        //if the table is empty, return false
        if (cartTable.Rows.Count == 0) { return false; }
        //search for the isbn
        foreach (DataRow row in cartTable.Rows)
        {
            if (row["ISBN"].ToString().CompareTo(isbn) == 0) { return true; }
        }//end foreach
        return false;
    }//end exists

    /// <summary>
    /// Sets the quantity of the specified item in the shopping cart.
    /// </summary>
    /// <param name="isbn">
    /// isbn of the item to be changed
    /// </param>
    /// <param name="quantity">
    /// The new quantity of the item
    /// </param>
    public void setQuantity(string isbn, int quantity)
    {
        if (!exists(isbn)) { return; }

        DataRow row = getRow(isbn);

        row["Quantity"] = quantity;

    }//end setQuantity

    /// <summary>
    /// Retrieves the total price of all items in the shopping cart.
    /// </summary>
    /// <returns>
    /// Total price of all items in the DataTable object.
    /// </returns>
    public Decimal getTotal()
    {
        decimal total = 0.00M;
        foreach (DataRow row in cartTable.Rows)
        {
            total += Int16.Parse(row["Quantity"].ToString()) * Decimal.Parse(row["Price"].ToString());
        }

        return total;
    }//end getTotal

    /// <summary>
    /// Resets the shopping cart data. Clears the cart.
    /// </summary>
    public void reset()
    {
        createCartTable();
    }// end reset

}//end class CartData
